package lfp.service.sender;

import org.apache.log4j.Logger;

import java.util.ResourceBundle;
import java.util.PropertyResourceBundle;

/**
 * Created by IntelliJ IDEA.
 * User: zhangsiyuan
 * Date: 2007-8-17
 * Time: 9:51:20
 */
public class ClientFactory {
    private static Logger log = Logger.getLogger(ClientFactory.class);
    private final static int MAX_CONNECTION = 5;
    private final static int MAX_AVAILABLE_HOST = 2;
    private static ResourceBundle bundle;

    static {
        bundle = PropertyResourceBundle.getBundle("config.serverHost");
    }

    private boolean bConnected;
    private boolean bHaveDone;
    private SenderClient senderClient;
    private int hostNameId;

    // ===================== constructor ==========================
    public ClientFactory() {
        bConnected = false;
        bHaveDone = false;
        hostNameId = 0;
    }

    // ====================== private ===========================
    private void initialClient(String hostName, int port) {
        senderClient = new SenderClient(hostName, port);
        if (senderClient.getClient() != null) {
            bConnected = true;
        }
    }

    private String nextHostName() {
        hostNameId++;
        String marker = "server.hostName";
        String hostName;
        try {
            hostName = bundle.getString(marker + hostNameId);
        } catch (NullPointerException e) {
            log.info("can't find available host!");
            return null;
        }
        return hostName;
    }

    private int getPort() {
        int port = 0;
        try {
            port = Integer.valueOf(bundle.getString("server.port"));
        } catch (NullPointerException e) {
            log.info("can't find available port!");
        }
        return port;
    }

    // ====================== app ==============================
    public SenderClient getSenderClient() {
        Thread reConnectionThread = new ReConnection();
        reConnectionThread.start();
        while(true) {
            if(bHaveDone || bConnected) {
                return senderClient;
            }
        }
    }

    class ReConnection extends Thread {
        public void run() {
            int connections = 0;
            String hostName = null;
            int port = getPort();
            while (connections < MAX_AVAILABLE_HOST * MAX_CONNECTION && !bConnected) {
                if (connections % MAX_CONNECTION == 0){
                    hostName = nextHostName();
                }
                initialClient(hostName, port);
                connections++;
                try {
                    Thread.sleep(5 * 1000);
                } catch (InterruptedException e) {
                    log.info("ReConnection break!");
                }
            }
            bHaveDone = true;
        }
    }

    public static SenderClient getInstance() {
        ClientFactory clientFactory = new ClientFactory();
        return clientFactory.getSenderClient();
    }
}
